﻿using System;
using System.Linq;
using Dexter.Search.Lucene.DocumentDefinition;
using Lucene.Net.Documents;
using Lucene.Net.Search;
using Lucene.Net.Store;

namespace Dexter.Search.Lucene.Wrapper {
	public class SearchService : IDisposable {
		readonly Directory luceneDirectory;
		private bool isDisposed;
		private Searcher luceneSearcher;

		public SearchService ( Directory luceneDirectory ) {
			this.luceneDirectory = luceneDirectory;
		}

		public void Dispose ( ) {
			if (!this.isDisposed && ( this.luceneSearcher != null )) {
				this.luceneSearcher.Close ( );
			}
			this.luceneSearcher = null;
		}

		public Searcher GetSearcher ( ) {
			if (this.isDisposed) {
				this.isDisposed = false;
			}
			return this.luceneSearcher ?? ( this.luceneSearcher = new IndexSearcher ( luceneDirectory , true ) );
		}

		public SearchResult<Document> SearchIndex ( Query query ) {
			return this.SearchIndex ( query, new DocumentResultDefinition ( ) );
		}

		public SearchResult<T> SearchIndex<T> ( Query query, IResultDefinition<T> definition ) {
			Searcher searcher = this.GetSearcher ( );
			return new SearchResult<T> ( searcher.Search ( query , 25000 ).scoreDocs.Select ( h => searcher.Doc ( h.doc ) ) , definition );
		}
	}
}
